home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / DOC.PAK / TDUMP.TXT < prev   
Text File  |  1997-05-06  |  60KB  |  1,530 lines

  1. /*********************************************************************/
  2.                         TDUMP.EXE Utility Program
  3.  
  4. This file contains information on:
  5.  
  6. 1.  TDUMP: The file inspecting utility
  7. 2.  Understanding "Undefined Symbol" Error Messages
  8. 3.  Resolving Undefined Symbol linker messages
  9. 4.  Borland Open Architecture: Name Mangling
  10.  
  11.  
  12. ===================================================================
  13. 1.  TDUMP: The file inspecting utility
  14. ===================================================================
  15. TDUMP.EXE is a utility that you use to examine the structure and
  16. contents of files.
  17.  
  18. TDUMP organizes the output display according to the extension of the
  19. file you're dumping. If the file extension is recognizable, TDUMP
  20. displays the file's components according to the file type. TDUMP
  21. recognizes many file extensions, including .EXE, .OBJ, and .LIB files.
  22. If TDUMP doesn't recognize an extension, it produces a hexadecimal dump
  23. of the file. You can control the output format by using command-line
  24. options when you start the TDUMP (these command-line options are
  25. described later).
  26.  
  27.  
  28. TDUMP syntax
  29. ------------
  30. The syntax for TDUMP is:
  31.  
  32.   TDUMP [<options>] <Inputfile> [<Listfile>] [<options>]
  33.  
  34.   o  <options> stands for any of the TDUMP options discussed in the
  35.      next section. For a list of the available command-line options,
  36.      type TDUMP, then press <Enter> at the DOS prompt.
  37.  
  38.   o  <Inputfile> is the file whose structure you want to display (or
  39.      "dump").
  40.  
  41.   o  <Listfile> is an optional output file name. Note that you can
  42.      also use the standard DOS redirection command ">" to create an
  43.      output file.
  44.  
  45.  
  46. TDUMP command-line options
  47. --------------------------
  48. You can use several option switches at a time with TDUMP. Because you can start
  49. each option with either a hyphen or a forward slash, the following two commands
  50. are equivalent:
  51.  
  52.   TDUMP -el -v demo.exe
  53.  
  54.   TDUMP /el /v demo.exe
  55.  
  56.  
  57. The -a and -a7 options
  58. - - - - - - - - - - - -
  59. TDUMP automatically adjusts its output display according to the file extension
  60. type. However, you can force an ASCII file display using either the -a or -a7
  61. options:
  62.  
  63.   o  -a  produces an ASCII file display that shows the offset and the
  64.      contents using the displayable ASCII characters. TDUMP displays
  65.      non-displayable characters (like control characters) as a period.
  66.  
  67.   o  -a7 converts high-ASCII characters to their low-ASCII
  68.      equivalents. This is useful if the file you are dumping sets
  69.      high-ASCII characters as flags (WordStar files do this).
  70.  
  71.  
  72. The -b# option
  73. - - - - - - - -
  74. The -b# option allows you to display information beginning at a specified offset.
  75. For example, if you wanted a dump of MYFILE starting from offset 100, you would
  76. use the following command:
  77.  
  78.   TDUMP -b100 MYFILE
  79.  
  80.  
  81. The -d option
  82.  - - - - - - -
  83. The -d option causes TDUMP to dump any Borland 32-bit debug information found in
  84. the .OBJ file. If you do not specify this option, TDUMP displays raw data only.
  85.  
  86.  
  87. The -e, -el, -er and -ex options
  88. - - - - - - - - - - - - - - - - -
  89. All four options force TDUMP to display the file as an executable (.EXE) file.
  90.  
  91. An .EXE file display consists of information contained within a file that is used
  92. by the operating system when loading a file. If symbolic debugging information is
  93. present (Turbo Debugger or MicrosoftCodeView), TDUMP displays it.
  94.  
  95. TDUMP displays information for DOS executable files, NEW style executable files
  96. (Microsoft Windows and OS/2 .EXEs and DLLs), and Linear Executable files.
  97.  
  98.   o  -el suppresses line numbers in the display.
  99.  
  100.   o  -er suppresses the display of the relocation table.
  101.  
  102.   o  -ex prevents the display of New style executable information.
  103.      This means TDUMP will only display information for the DOS
  104.      "stub" program.
  105.  
  106.  
  107. The -h option
  108. - - - - - - - -
  109. The -h option displays the dump file in hexadecimal (hex) format. Hex format
  110. consists of a column of offset numbers, 16 columns of hex numbers, and their ASCII
  111. equivalents (a period appears where no displayable ASCII character occurs).
  112.  
  113. If TDUMP doesn't recognize the input file's extension, it displays the file in hex
  114. format (unless an option is used to indicate another format).
  115.  
  116.  
  117. The -l and -li options
  118. - - - - - - - - - - - -
  119. The -l option displays the output file in library (.LIB) file format. A library
  120. file is a collection of object files (see the -o option for more on object files).
  121. The library file dump displays library-specific information, object files, and
  122. records in the object file.
  123.  
  124. The -li option tells TDUMP to display a short form of "impdef" records when
  125. dumping import libraries. You can also specify a search string using the following
  126. syntax:
  127.     -li=<string>
  128.  
  129. For example, the command
  130.     TDUMP -li=codeptr import.lib
  131. results in the following output:
  132.     Impdef:(ord) KERNAL.0336=ISBADCODEPTR
  133. This output shows that the function is exported by ordinal, whose ordinal value is
  134. 336 (decimal). In addition, the output displays the module and function name.
  135.  
  136. If you give the command
  137.     TDUMP -li=walk import32.lib
  138. TDUMP displays:
  139.     Impdef:(name) KERNEL32.????=HEAPWALK
  140. This shows the output of a function exported by name.
  141.  
  142.  
  143. The -m option
  144. - - - - - - -
  145. The -m option leaves C++ names occurring in object files, executable files, and
  146. Turbo Debugger symbolic information files in "mangled" format. This option is
  147. helpful in determining how the C++ compiler "mangles" a given function name and
  148. its arguments.
  149.  
  150.  
  151. The -o, -oc, -oi, and -ox options
  152. ---------------------------------
  153. The -o option displays the file as an object (.OBJ) file. An object file display
  154. contains descriptions of the command records that pass commands and data to the
  155. linker, telling it how to create an .EXE file.
  156.  
  157. The display format shows each record and its associated data on a record-by-record
  158. basis.
  159.  
  160.   o  -oc causes TDUMP to perform a cyclic redundancy test (CRC) on
  161.      each record encountered. The display differs from the -o display
  162.      only if an erroneous CRC check is encountered (the TDUMP CRC
  163.      value differs from the record's CRC byte).
  164.  
  165.   o  -oi<id> includes only specified record types in the object module
  166.      dump. Replace <id> with the name of the record to be displayed.
  167.      For instance,
  168.  
  169.         TDUMP -oiPUBDEF MYMODULE.OBJ
  170.  
  171.      produces an object module display for MYMODULE.OBJ that displays
  172.      only the PUBDEF records.
  173.  
  174.   o  -ox<id> excludes designated record types from the object module
  175.      dump. Replace <id> with the record name not to be displayed. For
  176.      instance,
  177.  
  178.         TDUMP -oxPUBDEF MYMODULE.OBJ
  179.  
  180.      produces an object module display for MYMODULE.OBJ that excludes
  181.      the PUBDEF records.
  182.  
  183.   o  The -ox and -oi options are helpful in finding errors that occur
  184.      during linking. By examining the spelling and case of EXTDEF and
  185.      PUBDEF symbols, you can resolve many linking problems. For
  186.      instance, if you receive an "unresolved external" message from
  187.      the linker, use "TDUMP -oiEXTDEF" to display the external
  188.      definitions occurring in the module causing the error. Then, use
  189.      "TDUMP -oiPUBDEF" on the module containing the public symbol
  190.      which the linker could not match.
  191.  
  192. Another use for the -oi switch is to check the names and sizes of the segments
  193. generated in a particular module. For instance,
  194.  
  195.   TDUMP -oiSEGDEF MYMODULE.OBJ
  196.  
  197. displays the names, attributes, and sizes of all of the segments in MYMODULE.
  198.  
  199. Note: To get a list of record types for -0i and -ox, use the command-line
  200.       options -oi? and -ox?.
  201.  
  202.  
  203. The -R option
  204. - - - - - - -
  205. The -R option causes TDUMP to dump relocation tables from 32-bit PE (Win32) format
  206. images. The default is to suppress these dumps.
  207.  
  208.  
  209. The -v option
  210. - - - - - - -
  211. The -v option is used to create a verbose display. If you use -v with an .OBJ or
  212. .LIB file, TDUMP produces a hexadecimal dump of the record's contents without any
  213. comments about the records.
  214.  
  215. If you use TDUMP on a Turbo Debugger symbol table, it displays the information
  216. tables in the order in which it encounters them. TDUMP doesn't combine information
  217. from several tables to give a more meaningful display on a per-module basis.
  218.  
  219.  
  220. ===================================================================
  221. 2.  Understanding "Undefined Symbol" Error Messages
  222. ===================================================================
  223. One of the most common error messages seen by developers using a C or
  224. C++ compiler is "undefined symbol." This document provides a general
  225. description of what causes undefined symbol error messages, as well as
  226. instructions on solving specific undefined symbol errors.
  227.  
  228. The following error message are treated in order:
  229.   UNDEFINED SYMBOL AT COMPILE TIME
  230.   UNDEFINED SYMBOL AT LINK TIME
  231.   OTHER UNDEFINED SYMBOL ERRORS
  232.   o  UNDEFINED SYMBOL WHEN LINKING A BORLAND EXAMPLE
  233.   o  UNDEFINED SYMBOL WHEN TLINKING FROM DOS COMMAND LINE
  234.   o  UNDEFINED SYMBOL LINKING C/C++ AND ASSEMBLY MODULES
  235.   o  UNDEFINED SYMBOL LINKING C++ WITH C OR ASSEMBLY MODULES
  236.   o  UNDEFINED SYMBOL: '_main' IN MODULE C0.ASM
  237.   o  UNDEFINED SYMBOL LINKING A DLL
  238.   o  UNDEFINED SYMBOL: A PSEUDO REGISTER (ie. _AX)
  239.   o  UNDEFINED SYMBOL: 'FIWRQQ'
  240.   o  UNDEFINED SYMBOL: AN IOSTREAM CLASS MEMBER
  241.   o  UNDEFINED SYMBOL: 'abort()'
  242.   o  UNDEFINED SYMBOL: '_exitclean()'
  243.   o  UNDEFINED SYMBOL: LLSH or SCOPY or FMUL or FDIV
  244.   o  UNDEFINED SYMBOL: STATIC POINTER TO A CLASS MEMBER FUNCTION
  245.   o  UNDEFINED SYMBOL: '_WSPRINTF'
  246.   o  UNDEFINED SYMBOL: 'fidrqq'
  247.   o  UNDEFINED SYMBOL IN WINDOWS.H
  248.   o  UNDEFINED SYMBOL USING TCLASDLL.LIB
  249.   o  UNDEFINED SYMBOL USING SELECTORS PROVIDED BY WINDOWS
  250.   o  UNDEFINED SYMBOL: 'ChangeSelector'
  251.   o  UNDEFINED SYMBOLS USING THE OBJECTWINDOWS LIBRARY (OWL)
  252.   o  UNDEFINED SYMBOL: 'Object::new(unsigned int)'
  253.   GETTING A CLOSER LOOK
  254.   o  USING TDUMP TO RESOLVE UNDEFINED SYMBOLS
  255.   o  USING IMPDEF TO RESOLVE UNDEFINED SYMBOLS IN A DLL
  256.  
  257.  
  258. UNDEFINED SYMBOL AT COMPILE TIME
  259. --------------------------------
  260. An undefined symbol at compile time indicates that the named
  261. identifier was used in the named source file, but had no definition in
  262. the source file. This is usually caused by a misspelled identifier
  263. name, or missing declaration of the identifier used.
  264.  
  265. EXAMPLE 1:
  266.     int main(void)
  267.     {
  268.         test = 1;
  269.         return 0;
  270.     }
  271.  
  272. The code shown in Example 1 generates an undefined symbol error if the
  273. variable "test" was not declared in either an included header file or
  274. in the actual source file itself.
  275.  
  276. EXAMPLE 2:
  277.     int main(void)
  278.     {
  279.         int test;
  280.         Test = 1;
  281.         return 0;
  282.     }
  283.  
  284. The code shown in Example 2 causes an undefined symbol error message
  285. to be displayed because the variable "Test" was not spelled as it was
  286. declared. Remember that C and C++ are case-sensitive languages.
  287.  
  288.  
  289. UNDEFINED SYMBOL AT LINK TIME
  290. -----------------------------
  291. When linking multi-file projects, the linker must resolve all
  292. references to functions and global variables shared between modules.
  293. When these references cannot be resolved, the linker generates
  294. an "undefined symbol" error message. This means that after searching
  295. all of the object files and libraries which are included in the link,
  296. the linker was unable to find a declaration for an identifier you
  297. used. This can be caused by:
  298.  
  299.   o  Forgetting to include a needed object module or library in
  300.      your link (project file, response file, or command line).
  301.  
  302.   o  Misspelling the name of the undefined symbol either where it
  303.      was used or where it was declared.
  304.  
  305.   o  Accidentally declaring a global variable as "extern."
  306.  
  307.   o  Forgetting to use extern "C" to disable name mangling when you're
  308.      mixing C++ with C or Assembly modules. See the specific entry on
  309.      this subject elsewhere in this document or consult the
  310.      HELPME!.DOC file included with the product.
  311.  
  312.   o  Turning OFF Generate Underbars in one of the modules you're
  313.      linking.
  314.  
  315. If all else fails, use TDUMP to dump both object modules and note any
  316. difference between the symbols used. This will usually give enough
  317. insight to resolve the problem. For more information on using TDUMP to
  318. resolve undefined symbol errors, see the "Getting a Closer
  319. Look "section in this document.
  320.  
  321.  
  322. OTHER UNDEFINED SYMBOL ERRORS
  323. ------------------------------
  324. The following list provides solutions to some of the more common
  325. causes of undefined symbol errors:
  326.  
  327.   o  UNDEFINED SYMBOL WHEN LINKING A BORLAND EXAMPLE
  328.      Almost all of Borland's examples come with project files. You
  329.      must use the project file when building the example to ensure
  330.      that all necessary modules are linked and all the necessary
  331.      settings are defined.
  332.  
  333.   o  UNDEFINED SYMBOL WHEN TLINKING FROM DOS COMMAND LINE
  334.      The TLINK command line must have the libraries in the following
  335.      order ( GRAPHICS.LIB + <user libs> + EMU.LIB + MATH (S,T,C,M,L -
  336.      for model) + C (S,T,C,M,L - for model)
  337.  
  338.   o  UNDEFINED SYMBOL LINKING C/C++ AND ASSEMBLY MODULES
  339.      There are several sources of undefined symbol errors when trying
  340.      to link assembly with C or C++ modules:
  341.  
  342.        o  Turbo Assembler generates all upper-case symbols unless you
  343.           specify /ml or /mx on the assembly command line. Since C
  344.           modules are, by default, case sensitive, failing to do this
  345.           will result in undefined symbols for all symbols that are
  346.           not completely upper case in the C module(s).
  347.  
  348.        o  The symbols in the assembly file being referenced from a C
  349.           module must be declared using a PUBLIC directive. TLINK does
  350.           not consider symbols which are not declared PUBLIC when it
  351.           attempts to resolve an undefined symbol.
  352.  
  353.        o  All symbols in the assembly module that are referenced in
  354.           the C module must be prototyped/declared as extern in the C
  355.           module -- the compiler generates undefined symbol errors for
  356.           all symbols not declared in this manner. In addition, all
  357.           symbols in the assembly module that are referenced from a C
  358.           module must have an underscore prefix. This naming
  359.           convention must be used in the assembly module. You can
  360.           either do this explicitly (_symbol) or you can use:
  361.  
  362.             .model <memory model used>, C
  363.  
  364.           to specify this implicitly for all symbols.
  365.  
  366.           IMPORTANT NOTE: If you put underscores in front of your
  367.           assembly routines and also use the .model (memory model)
  368.           C directive, the public symbol will be generated with two
  369.           underscores; consequently an undefined symbol error is
  370.           generated.
  371.  
  372.           If all else fails, TDUMP both object modules and note any
  373.           difference between symbols. This will usually give enough
  374.           insight to resolve the problem. For more information on
  375.           using TDUMP to resolve undefined symbol errors see the
  376.           "Getting a Closer Look" section in this document.
  377.  
  378.   o  UNDEFINED SYMBOL LINKING C++ WITH C OR ASSEMBLY MODULES
  379.      C++ is a strongly typed language. In order to support type-safe
  380.      linkage (as well as function overloading), Borland C++ must
  381.      attach information to the symbols generated for function names
  382.      and variables. When this is done, the symbol will no longer match
  383.      the standard C style function name. In order to link correctly
  384.      with C or assembly modules, the compiler must be notified that
  385.      the symbol is to be in the standard C style (non-encoded) rather
  386.      than employing C++ name-mangling (encoded). This is done by
  387.      prototyping the function as type extern "C". Here is a quick
  388.      example:
  389.  
  390.        extern "C" int normal_c_func( float, int, char );
  391.  
  392.      For an additional example, you may want to look at the header
  393.      files which came with the product. One such header file is
  394.      stdio.h.
  395.  
  396.   o  UNDEFINED SYMBOL: '_main' IN MODULE C0.ASM
  397.      Every DOS C program must contain a function called main(). This
  398.      is the first function executed in your program. The function name
  399.      must be all in lower case. If your program does not have one,
  400.      create one. If you are using multiple source files, the file that
  401.      contains the function main() must be one of the files listed in
  402.      the project.
  403.  
  404.      Note that an underscore character '_' is prepended to all
  405.      external Borland C++ symbols.
  406.  
  407.      In addition to an absent, misspelled or mis-cased symbol main,
  408.      there are two additional common causes:
  409.  
  410.        o  The "generate underbars" option is disabled.
  411.  
  412.        o  The Pascal calling Convention rather than the C calling
  413.           convention is selected.
  414.  
  415.  
  416.   o  UNDEFINED SYMBOL LINKING A DLL
  417.      It is relatively simple to link a DLL to your source:
  418.  
  419.        1)  Create a .LIB from the .DLL using Borland's implib utility.
  420.  
  421.        2)  Include the .LIB in your project if you're using the IDE or
  422.            in your TLINK command if you're using the command-line
  423.            compiler or linker.
  424.  
  425.        3)  Turn case sensitive link ON.
  426.  
  427.        4)  Turn case sensitive exports ON.
  428.  
  429.      The issues of linking C++ with C, assembly, or any other language
  430.      still apply. See the sections on linking C++, C, and assembly in
  431.      this document.
  432.  
  433.      If the link still fails, the techniques in the section "Getting A
  434.      Closer Look" should help you resolve the problem.
  435.  
  436.   o  UNDEFINED SYMBOL: A PSEUDO REGISTER (i.e. _AX)
  437.      Pseudo registers are only allowed in the Borland C++ and ANSI
  438.      modes of the compiler. You can change this setting in the
  439.      Options | Compiler | Source menu.
  440.  
  441.   o  UNDEFINED SYMBOL: 'FIWRQQ'
  442.      Your program uses floating point routines directly (or
  443.      indirectly) and you have NONE selected for floating point. Or,
  444.      you are using TLINK and have forgotten to include EMU.LIB or
  445.      FP87.LIB on the command line.
  446.  
  447.   o  UNDEFINED SYMBOL: AN IOSTREAM CLASS MEMBER
  448.      If you are using the Integrated Development Environment, simply
  449.      turn off Options | Compiler | Code Generation | Unsigned
  450.      Characters.
  451.  
  452.      If you are using the command-line compiler, simply remove the
  453.      '-K' option.
  454.  
  455.   o  UNDEFINED SYMBOL: 'abort()'
  456.      The sole purpose of abort is to print the error message
  457.  
  458.        "Abnormal Program Termination"
  459.  
  460.      and exit the program with an error code of 3. This function is
  461.      located in the startup code C0.ASM. Linker errors indicating that
  462.      abort() is an undefined symbol are only possible if the standard
  463.      startup code is not being linked into a project. Although this is
  464.      not a common C/C++ development practice, it is to be expected
  465.      when linking in code written other languages such Microsoft
  466.      Fortran, Clipper, or in cases where embedded systems are being
  467.      developed. To resolve the undefined symbol, extract the abort()
  468.      function from the startup code and make a separate object out of
  469.      it to be linked into the project.
  470.  
  471.   o  UNDEFINED SYMBOL: '_exitclean()'
  472.      There is a function called _exitclean which is new to Turbo C++.
  473.      Users moving from Turbo C 2.0 to Turbo C++ may encounter
  474.      _exitclean() as an undefined symbol at link time. _exitclean() is
  475.      defined in the Turbo C++ startup code. Users creating embedded
  476.      system (ROMable code), who do not use the standard Turbo C++
  477.      startup code, are likely to encounter _exitclean() as an
  478.      undefined symbol. These users can strip the function from the
  479.      C0.ASM file and create a separate .OBJ file which can be linked.
  480.      Another option would be to purchase the Borland C++ RTL source and make
  481.      the necessary adjustments.
  482.  
  483.   o  UNDEFINED SYMBOL: LLSH or SCOPY or FMUL or FDIV
  484.      The helper functions have changed their names from Turbo C 2.0 to
  485.      Turbo C++. This can lead to many undefined symbol issues.
  486.  
  487.      When LLSH or SCOPY or FMUL or FDIV (note no underscores here)
  488.      appear as undefined symbols at link time, it is likely that an
  489.      object module or library has code generated a call to some helper
  490.      function from the Turbo C 2.0 libraries. The solution is to
  491.      simply recompile all objects from source. You can do this by
  492.      choosing Compile | BuildAll from the menu in the IDE.
  493.  
  494.   o  UNDEFINED SYMBOL: STATIC POINTER TO A CLASS MEMBER FUNCTION
  495.      Any static member of a class must be initialized--if not that
  496.      static member generates an undefined symbol error. The following
  497.      is an example of how to initialize a static pointer to class
  498.      member function of a class is initialized:
  499.  
  500.      // When testing static member initialization, you must
  501.      // declare an instance of the class in a main function;
  502.      // otherwise, the linker has no reference which it must
  503.      // try to resolve, and the undefined symbol error will
  504.      // not be seen - thus you won't know that your
  505.      // initialization was in error.
  506.  
  507.      #include <iostream.h>
  508.  
  509.      // used to allow global initialization of static member pointer
  510.      typedef void (*fptr)();
  511.  
  512.      // declare class containing static members
  513.      class First
  514.      {
  515.        public:
  516.           static fptr statptr;
  517.      };
  518.  
  519.      // initialize static members of class First
  520.      fptr First::statptr = NULL;
  521.  
  522.      int main(void) {
  523.           First fVar;
  524.  
  525.           if (fVar.statptr == NULL)
  526.                cout << "fVar.statptr is NULL: " <<
  527.                fVar.statptr << endl;
  528.  
  529.           return 0;
  530.      } // end of main()
  531.  
  532.   o  UNDEFINED SYMBOL: '_WSPRINTF'
  533.      Turn off the "Case-sensitive exports" and "Case-sensitive link"
  534.      options. If you are using the command linker, don't use the /c
  535.      switch. If you are invoking the linker from the BCC(x) command
  536.      line, use the -lc- switch. If you are using the IDE, go to the
  537.      linker options dialog box and turn off the case sensitivity
  538.      switch.
  539.  
  540.   o  UNDEFINED SYMBOL: 'fidrqq'
  541.      You will get an undefined symbol fidrqq when using the Integrated
  542.      Development Environment if you have the Options | Compiler | Code
  543.      Generation | More | Floating Point Option set to NONE and you are
  544.      using floating point arithmetic in your program. In order to best
  545.      solve this problem you must set the IDE option for Floating Point
  546.      to either the emulation choice or to the 80x87 choice. Note that
  547.      if you choose an 80x87 setting the application generated by the
  548.      compiler will require an 80x87 chip to be present at run-time.
  549.      Use this setting only when truly appropriate.
  550.  
  551.   o  UNDEFINED SYMBOL IN WINDOWS.H
  552.      Make sure you are using the windows.h file that came with Borland
  553.      C++, NOT the windows.h that came with the Microsoft Windows SDK.
  554.      If you include the Microsoft windows.h file you will get many
  555.      undefined symbols including WINMAIN in caps and translatemessage
  556.      in lower case. Use our windows.h file instead of Microsoft's when
  557.      you are using our compiler.
  558.  
  559.   o  UNDEFINED SYMBOL USING TCLASDLL.LIB
  560.      To use the DLL version of the container class library you must do
  561.      ALL of the following:
  562.  
  563.        o  Use the large memory model
  564.  
  565.        o  Use Smart Callbacks
  566.  
  567.        o  Turn case sensitive link ON
  568.  
  569.        o  Turn case sensitive exports ON
  570.  
  571.        o  Use the DLL version of the RTL
  572.  
  573.        o  Define _CLASSDLL
  574.  
  575.   o  UNDEFINED SYMBOL USING SELECTORS PROVIDED BY WINDOWS
  576.      If you are using _C000h or other selectors provided by Windows
  577.      and they are coming up as undefined symbols, perhaps you are
  578.      compiling in C++ mode and forgot to extern "C" them.
  579.  
  580.      Programming in C:
  581.        extern WORD _C000h
  582.  
  583.      Programming in C++:
  584.        extern "C" WORD _C000h
  585.  
  586.   o  UNDEFINED SYMBOL: 'ChangeSelector'
  587.      The Windows API function ChangeSelector() has the wrong name in
  588.      KERNEL.EXE for Windows 3.0, and therefore in IMPORT.LIB. The name
  589.      given to this function (and this is NOT a joke) is 
  590.      PrestoChangoSelector().
  591.  
  592.      Use PrestoChangoSelector() in your program in place of
  593.      ChangeSelector() and all will be well.
  594.  
  595.   o  UNDEFINED SYMBOLS USING THE OBJECTWINDOWS LIBRARY (OWL)
  596.      If you get any of the following the undefined symbols:
  597.  
  598.        TApplication(unsigned char far *, unsigned int, unsigned int,
  599.            unsigned char far *, int )
  600.  
  601.        and
  602.  
  603.        TWindow::TWindow(TWindowsObject near *, unsigned char far *,
  604.            TModule near *)
  605.  
  606.        and are using the DLL versions of OWL and the Class Library,
  607.        you must define _CLASSDLL in Options | Compiler | Code
  608.        Generation | defines combo box.
  609.  
  610.        It could be because you have forced unsigned characters. The
  611.        functions in the .lib take signed characters and thus if you
  612.        compile to use unsigned characters, the symbols will not match.
  613.  
  614.        Using the Integrated Development Environment be sure to turn
  615.        off Options | Compiler | Code Generation | Unsigned Characters.
  616.  
  617.        If you are using the command line compiler be sure to remove
  618.        the -K option to solve this problem.
  619.  
  620.   o  UNDEFINED SYMBOL: 'Object::new(unsigned int)'
  621.      You forgot to link with the TCLASDLL.LIB file where it is
  622.      defined!
  623.  
  624.      Basically the problem is that you are mixing both STATIC and
  625.      DYNAMIC LINK libraries into the application. You must use only
  626.      one or the other. If you are working in the IDE, change the
  627.      LINKER options section for libraries.
  628.  
  629.      If you are using the dynamic link library, remember to set
  630.      _CLASSDLL and Build All.
  631.  
  632.      If you are using the command line compiler and linker, just be
  633.      sure to specify the correct set of library files. For specific
  634.      information on the "correct set of library files" please see the
  635.      documentation included with the product as library names tend to
  636.      change from version to version.
  637.  
  638.  
  639. GETTING A CLOSER LOOK
  640. ---------------------
  641. Borland provides tools that you can use to determine exactly what the
  642. linker is seeing when it is trying to match symbols: TDUMP and IMPDEF.
  643. This section provides some simple techniques for using these utilities
  644. to resolve undefined symbol errors.
  645.  
  646.   o  USING TDUMP TO RESOLVE UNDEFINED SYMBOLS
  647.      TDUMP can be used to list the symbols in a .OBJ or a static .LIB
  648.      that the linker is having trouble matching.
  649.  
  650.      First, TDUMP the module that is trying to reference the symbol.
  651.      For example, if main.cpp is trying to access a function, myfunc()
  652.      in myfuncs.cpp and is getting "Undefined symbol myfunc() in
  653.      module main.cpp",
  654.  
  655.          tdump -m -oiEXTDEF main.obj > main.ext
  656.  
  657.      Then, TDUMP the module in which the symbol is defined.
  658.  
  659.          tdump -m -oiPUBDEF myfuncs.obj > myfunc.pub
  660.  
  661.      Using a text editor find the symbol associated with the error in
  662.      each file. If they are not the same, then you have verified that
  663.      the linker is correct in generating the error. You must check
  664.      your code and verify that the compiler is seeing the same
  665.      declaration for the symbol when each module is being compiled.
  666.  
  667.      You can use TDUMP to look at a static .LIB file the same way you
  668.      look at an .OBJ. file.
  669.  
  670.          tdump -m -oiPUBDEF mystatic.lib > mystatic.pub
  671.  
  672.      To use TDUMP with an implib,
  673.  
  674.          tdump -m -oiTHEADR mydll.lib > mydll.pub
  675.  
  676.      You can also use IMPDEF to view the symbols exported by a DLL.
  677.  
  678.  
  679.   o  USING IMPDEF TO RESOLVE UNDEFINED SYMBOLS IN A DLL
  680.      If you are trying to link a Borland generated DLL with another
  681.      language or product and are getting undefined symbol errors, you
  682.      should verify that the names or the ordinals that are being
  683.      exported by the DLL are the same as your application expects.
  684.  
  685.      This can be done by generating a .DEF file with the utility
  686.      IMPDEF. For example, to create a .DEF file for MY.DLL,
  687.  
  688.         impdef my.def my.dll
  689.  
  690.      The .DEF file will have the exported symbol name and its ordinal
  691.      number. Remember that C++ mangles names. Your application must
  692.      expect the mangled symbol name to call the function in the DLL
  693.      properly. This can be a problem if the application automatically
  694.      uppercases the symbol name before trying to call the function. If
  695.      this is so, you must change the declaration of the function and
  696.      re-build your DLL.
  697.  
  698.  
  699. ===================================================================
  700. 3.  Resolving Undefined Symbol linker messages
  701. ===================================================================
  702. This section provides an overview of the Linking process and helps to
  703. identify causes of 'unresolved external symbols'.
  704.  
  705. The code for printf() is in a module in the run time library. When you
  706. call printf() in a C/C++ module, the compiler creates a record
  707. (referred to as EXTDEF - EXTernal DEFinition) that indicates the call
  708. to an external function. The linker then looks at that OBJ, along with
  709. all the other modules and libraries specified and attempts to find
  710. another module (.OBJ or .LIB) which defines/provides the
  711. symbolprintf().
  712.  
  713. If the linker cannot resolve the call to printf(), the linker
  714. generates an error indicating that printf() is an undefined symbol.
  715. The error message, however, is very often not the result of leaving
  716. out the module containing the symbol being looked for, but rather a
  717. discrepancy between the name used by the caller (the C/C++ module
  718. calling printf() in the case mentioned above) and the supplier (the
  719. LIBRARY containing the code to printf() ).
  720.  
  721. The *real* name of any symbol is almost always different from the
  722. name/identifier used by the programmer. For example, the *real* name
  723. (by *real* name we mean the identifier used/generated by the tools) of
  724. strcpy() is: '_strcpy()'. The *real* name of a symbol depends on the
  725. various settings and options. The relevant settings are list below:
  726.  
  727.   Calling Conventions:
  728.         > cdecl
  729.         > pascal
  730.         > fastcall
  731.  
  732.   Compiler Settings:
  733.         > generate underbars
  734.         > unsigned chars    ( C++ only )
  735.  
  736.   Optimizations:
  737.         > Object Data Calling   ( C++ only )
  738.  
  739.   Virtual Table:
  740.         > Far Virtual Tables
  741.  
  742.   Language used:
  743.         > C
  744.         > C++
  745.         > Assembly
  746.  
  747. Furthermore there are two options which affect how the linker attempts
  748. to match symbols:
  749.  
  750.         > Case sensitive link
  751.         > Case sensitive exports ( Windows only )
  752.  
  753. The following is a discussion of how the above mentioned options
  754. affect the *real* name of symbols, hence the resolution of symbols.
  755.  
  756.  
  757. Calling Conventions
  758. -------------------
  759. Borland and Turbo C++ both allow you to specify the default calling
  760. convention. This default can be overridden by using the
  761. 'pascal', '_fastcall' or 'cdecl' keywords. Whether set globally or on
  762. individual function instances, the calling convention affects the name
  763. of functions. By default, when the compiler encounters a function
  764. declared as,
  765.  
  766.     int Foo( int );    // or: int cdecl Foo( int );
  767.  
  768. the name generated is _Foo; that is, the resulting name has the same
  769. case but is preceded with a leading underscore. The generation of the
  770. underscore is the default behavior and is necessary when you link to
  771. the run time libraries. There is no 'printf()' symbol in the RTL
  772. (!),but there is a '_printf()'.
  773.  
  774. While the C calling convention implies 'Case Sensitivity' and
  775. 'Generation of Underbars', Borland/Turbo C++ provides separate
  776. settings for the generation of underbars and the calling convention
  777. Generation of Underbars can be controlled from the Options | Compiler|
  778. Advanced Code Generation Dialog, or the -u option from the command
  779. line ( -u- would turn it off, it is on by default). The 'Calling
  780. Convention' can be modified via the Options | Compiler |
  781. Entry/ExitCode Dialog.
  782.  
  783. If our function 'Foo' is declared with the pascal modifier, for
  784. example:
  785.  
  786.     int pascal Foo( int );
  787.  
  788. (or if the default 'Calling Convention' is set to 'PASCAL') the
  789. resulting name will be FOO--that is, all upper-case with no
  790. underscore. The '_fastcall' modifier is similar to 'cdecl' in regards
  791. to Case Sensitivity but the underscore character is replaced with '@'.
  792. Hence:
  793.  
  794.     int _fastcall Foo( int );
  795.  
  796. will result in the '@Foo' symbol.
  797.  
  798. Therefore, mismatching the calling conventions might result in
  799. 'Undefined Symbols.' Watch for clues in the undefined symbol name
  800. provided in the Linker error messages (look at the Case Sensitivity
  801. and any leading characters) to spot cases of incorrect settings in the
  802. 'Calling Convention' and/or 'Generation of Underbars'.
  803.  
  804.  
  805. NAME MANGLING:
  806. --------------
  807. The C++ language uses yet another naming convention as part of its
  808. implementation of 'type safe linkage.' Imagine a function myfunc()
  809. which take two longs [void myfunc( long, long );]. What if someone has
  810. it incorrectly prototyped in a calling module as taking two floats,
  811. for example void myfunc( float, float );. The results of such a call
  812. will be unpredictable. When using the C language, the linker would
  813. resolve such a call since the symbol the compiler uses to call the
  814. function taking two floats will be '_myfunc()', and the name the
  815. compiler used in the module which implements the function taking two
  816. longs is also '_myfunc()'.
  817.  
  818. In C++, however, the name the compiler generates for a function is a
  819. 'mangled' name: it is 'encrypted' based on the parameters types the
  820. function expects. In the scenario described in the prior paragraph, the
  821. call to myfunc() will not be resolved since the compiler generates
  822. different names for 'void myfunc( float, float )' and 'void myfunc(
  823. long, long )'.
  824.  
  825. Because a C++ function's mangled real name depends on the types of its
  826. parameters, if unsigned chars is used as a compiler option, it changes
  827. the name of functions declared to take a char, or char *. Unsigned
  828. chars is off by default, it is turned on under the Options |Compiler |
  829. Code generation menu. Or by specifying the -K option with the command
  830. line compiler. Watch out for potential 'Undefined Symbol' messages
  831. caused by a mismatched of char vs. unsigned char.
  832.  
  833. The 'virtual mechanism' of C++ is implemented via a table commonly
  834. referred to as the Virtual Table or the VMT (Virtual Method Table).
  835. Various settings of the Compiler dictate whether the Table ends up in
  836. the Default Data Segment or in a Far Segment (namely Memory
  837. Model, '_export' and 'huge' class modifiers, Virtual Table Control
  838. Optionsetc). To further enforce 'type- safe-linkage', the
  839. Borland/Turbo C++ compilers include the 'distance' of the Virtual Table
  840. as part of its 'Name-Mangling' logic. This prevents the linker from
  841. resolving function calls which would crash at run-time because of
  842. mismatched 'Virtual Table Control' settings. In the same token,
  843. Borland provides the 'Object Data Calling convention' for improved
  844. efficiency of C++ code. Once again, the 'Name-mangling' algorithm also
  845. reflects the enabling of 'Object Data Calling'. This ensures that
  846. function calls involving mismatched 'Object Data Calling' convention
  847. between caller and callee will be caught at link time (instead of
  848. resulting in erratic run-time behavior).
  849.  
  850. To illustrate the effect of 'Virtual Table Control' and 'Object
  851. DataCalling,' let's create a simple class and look at the effects of
  852. the various settings on the resulting names:
  853.  
  854. class  Test
  855. {
  856.      public:
  857.          virtual int Process( void );
  858. };
  859.  
  860. int main( void )
  861. {
  862.      Test t;
  863.      return t.Process();
  864. }
  865.  
  866. The following table illustrates the effects of Compiler Settings on
  867. the *actual* name generated for the member function 'int
  868. Test::Process(void)'.
  869.  
  870.      +----------------------------------------------------------+
  871.      | Object Call. | Far V. Tbl. | Huge Md. |  [ REAL  NAME ]  |
  872.      |--------------+-------------+-----------------------------+
  873.      |      No      |     No      |  No     > @Test@Process$qv  |
  874.      |--------------+-------------+-----------------------------+
  875.      |      No      |     Yes     |  No     > @Test@0Process$qv |
  876.      |--------------+-------------+-----------------------------+
  877.      |      Yes     |     No      |  No     > @Test@1Process$qv |
  878.      |--------------+-------------+-----------------------------+
  879.      |     Yes      |     No      |  Yes    > @Test@2Process$qv |
  880.      +--------------+-------------+-----------------------------+
  881.  
  882. NOTE: Using the '_export' or 'huge' keyword when defining a class
  883.       results in Far Virtual Tables for the class.
  884.  
  885. 'Undefined Symbol Messages' caused by mismatching Virtual Table
  886. Controls or Object Data Calling conventions may be hard to identify; it
  887. is often useful to use TDUMP.EXE to find the actual names of the
  888. unresolved symbols (however, watch out of any '0', '1' or '2' following
  889. the '@ClassName@' portion of the real names).
  890.  
  891.  
  892. LANGUAGE USED
  893. -------------
  894. By default assemblers (including TASM) do not modify public
  895. names--they merely convert symbols to upper case. With TASM, the /mx
  896. option forces the assembler to treat public symbols with case
  897. sensitivity. Without /mx, a call to _myfunc from an assembly module
  898. looks like _MYFUNC to the linker (this causes undefined symbol errors
  899. when linking C and assembly).
  900.  
  901. NOTE: TASM has an extension which causes the automatic generation of
  902. underscores. See. .MODEL <model>, Language directives in the TASM
  903. User's Guide.
  904.  
  905. As previously mentioned in the section about 'Name Mangling,' the
  906. C++ language uses a different naming convention than does the C
  907. language. This can result in undefined symbols when calling C from C++
  908. (or vice-versa). C++ modules should use the 'extern "C"' syntax when
  909. interfacing with C modules (see the Name Mangling section of
  910. Programmer's Guide for the proper syntax).
  911.  
  912.  
  913. LINKER SETTINGS
  914. ---------------
  915. By default, the linker treats _myfunc and _MYFUNC as different
  916. symbols. However, you can control whether the linker pays attention to
  917. Case Sensitivity via the Options | Linker | Settings dialog (IDE), or
  918. the /c option with TLINK (/c: Enables Case Sensitivity [default],
  919. /c-turns the option off).
  920.  
  921. For example, if the option is disabled, a call to _myfunc could be
  922. resolved to _MYFUNC.
  923.  
  924. When creating a Windows application, not only can you link to 'static'
  925. modules (.OBJs or .LIBs which are a collection of .OBJs), but you can
  926. also link to dynamic libraries where the resolution of the call is
  927. completed by Windows at load time. Functions residing in DLLs and
  928. called from an .EXE are said to be imported. Functions that are coded
  929. in an .EXE or .DLL, and are called by either Windows, .EXEs, or .DLLs
  930. are said to be exported.
  931.  
  932. Functions are imported in two ways: by listing them in the IMPORTS
  933. section of the .DEF file, or by linking to an import library. Functions
  934. can be exported by two methods: by using the _export keyword in the
  935. source code or listing the functions in the EXPORTS section of the
  936. .DEF file.
  937.  
  938. Suppose your application calls the symbol _myfunc which is in a
  939. DLL. The linker can treat symbols coming from an import library, or
  940. IMPORTS section of the .DEF file with or without case sensitivity,
  941. (determined by the setting of case sensitive exports under the Options
  942. | Linker | Settings Dialog or /C option on the TLINK command line). If
  943. this setting is NOT enabled, then the Linker treats symbols in import
  944. libs or IMPORTS sections as all uppercase. It then considers upper
  945. case symbols during the link phase. At that point it is doing normal
  946. linking using the setting of the case sensitive link option. If we are
  947. importing both _myfunc and _MYFUNC without the /C option, the linker
  948. can only resolve the call to _MYFUNC.
  949.  
  950. If you are calling _myfunc (a cdecl function) and are performing a
  951. case sensitive link, but do not have case sensitivity on
  952. EXPORTS, _myfunc will show up as undefined.
  953.  
  954.      > Imported cdecl functions and C++ names will link when /c
  955.      > and /C are both enabled, or neither are enabled.
  956.  
  957. C++ names are always generated with lowercase letters. When importing
  958. or exporting C++ names, it's recommended that you use both the /c
  959. and/C options.
  960.  
  961. Now let's apply the above to some common scenarios and provide
  962. possible diagnostics and suggestions:
  963.  
  964.  
  965. PROBLEM:
  966.      All the functions in a 3rd party library are undefined!
  967.  
  968. SOLUTION:
  969.      3rd party libraries must be explicitly linked in. To explicitly
  970.      link to a 3rd party library from the IDE, open a project file and
  971.      insert the .LIB file into the project file. The project file also
  972.      needs to have all of your source code files listed in it. From
  973.      the command line, insert the .LIB on your command line to TLINK.
  974.  
  975.  
  976. PROBLEM:
  977.      All the functions in the RTL are undefined!
  978.  
  979. SOLUTION:
  980.      You need to link in Cx.LIB, where x is the memory model. A
  981.      feature of the IDE in Turbo C++ and Borland C++ v2.x is that if
  982.      you put a .LIB in the project file which starts out as Cx where x
  983.      is a memory model, the new library overrides the normal run time
  984.      library, and the latter will not be linked in (for example, if
  985.      you're using a library named CSERVE.LIB). Rename any such
  986.      libraries, then the normal Cx.LIB will automatically be linked
  987.      in. (Borland C++ 4.x has a dialog for specifying which Run Time
  988.      Libraries should be linked in).
  989.  
  990.  
  991. PROBLEM:
  992.      When mixing C and C++ modules (.c and .cpp source) symbols are
  993.      undefined.
  994.  
  995. SOLUTION:
  996.      Because of name mangling (see above) the symbol the linker sees
  997.      being called from a C++ module will not look like the symbol in
  998.      the Cmodule. To turn name mangling off when prototyping
  999.      functions:
  1000.  
  1001.      // SOURCE.CPP
  1002.  
  1003.      extern "C" {
  1004.           int Cfunc1( void );
  1005.           int Cfunc2( int  );
  1006.      }
  1007.  
  1008. NOTE:  You can also disable name-mangling for functions written in
  1009. C++ and called from C.
  1010.  
  1011. A C++ compile will happen if the source code has a .CPP extension, or
  1012. Options | Compiler | C++ options use C++ compiler is set to always.
  1013.  
  1014.  
  1015. PROBLEM:
  1016.      randomize and other macros are coming up as undefined symbols.
  1017.  
  1018. SOLUTION:
  1019.      Turn keywords to Borland C++. Since some macros are not ANSI
  1020.      compatible, the header files will not define them if compiled
  1021.      with ANSI or UNIX keywords on.
  1022.  
  1023.  
  1024. PROBLEM:
  1025.      min and max are coming up undefined.
  1026.  
  1027. SOLUTION:
  1028.      These macros are only included in a C compile, and will not be
  1029.      seen by the compiler if compiling in C++. In C, you must
  1030.      #include <stdlib.h> to use them.
  1031.  
  1032.  
  1033. PROBLEM:
  1034.      I cannot get my assembly modules to link with my C/C++ program.
  1035.  
  1036. SOLUTION:
  1037.      For C++, see above. Otherwise, the .ASM must be assembled with
  1038.      case sensitivity on public symbols (/mx for TASM). It must also
  1039.      match the C naming convention, which will have an underscore in
  1040.      front of the name. So given the following code in a C module,
  1041.  
  1042.      int myfunc( void );
  1043.  
  1044. you need to
  1045.  
  1046.      call _myfunc
  1047.  
  1048.      from the assembly module. (NOTE: TASM has extensions which will
  1049.      automatically generate underscores for you). Also, make sure the
  1050.      .OBJ which has the assembly code is listed in the project file,
  1051.      or on the tlink line.
  1052.  
  1053.  
  1054. PROBLEM:
  1055.      wsprintf is coming up undefined.
  1056.  
  1057. SOLUTION:
  1058.      In Borland C++ 2.0, to use wsprintf when case sensitive exports
  1059.      is on, you need to reverse a define in windows.h via the
  1060.      following:
  1061.  
  1062.      #ifdef   wsprintf
  1063.      #undef   wsprintf
  1064.  
  1065.      #define  wsprintf wsprintf
  1066.      extern   "C" int FAR cdecl wsprintf( LPSTR, LPSTR, ... );
  1067.      #endif
  1068.  
  1069.      To call wsprintf (or any cdecl imported function ) with case
  1070.      sensitive exports off, you need to match an upper case name. Thus
  1071.      windows.h #defines wsprintf to be WSPRINTF. wsprintf is one of the
  1072.      cdecl functions from windows, so the compiler will generate a
  1073.      lower case symbol for when calling it.
  1074.  
  1075.  
  1076. PROBLEM:
  1077.      FIWRQQ and FIDRQQ are undefined
  1078.  
  1079. SOLUTION:
  1080.      These symbols are in the EMU or FP87 library. You must link it
  1081.      in explicitly when using TLINK, or set the IDE to link it in under
  1082.      the Options | Compiler | Advanced Code Generation Floating point
  1083.      box.
  1084.  
  1085.  
  1086. PROBLEM:
  1087.      Warning attempt to export non-public symbol ...
  1088.  
  1089. SOLUTION:
  1090.      The exports section of the .DEF file has a symbol which does not
  1091.      match one the compiler generated in the source code. This happens
  1092.      if:
  1093.  
  1094.   o  The source was compile in C++ (the symbol name is mangled).
  1095.      Resolve by exporting with the _export keyword, compiling in C,
  1096.      or by declaring the function as extern "C".
  1097.  
  1098.   o  Case sensitive exports is ON, you are exporting a PASCAL
  1099.      function, and exporting it like: WndProc. Resolve by
  1100.      exporting as WNDPROC or by turning case sensitive exports off.
  1101.  
  1102.   o  You are exporting a cdecl function. If declared as
  1103.          int myfunc( void );
  1104.      export as _myfunc and turn case sensitive exports on (or
  1105.      just use the _export keyword).
  1106.  
  1107.      NOTE: When using the '_export' keyword, it must be used in
  1108.            the prototype of the function. For example:
  1109.                int FAR _export myfunc( int );
  1110.  
  1111.  
  1112. PROBLEM:
  1113.      C++ and DLL linking problems.
  1114.  
  1115. SOLUTION:
  1116.      Classes declared in the DLL need to be declared as the following:
  1117.  
  1118.      class _export A
  1119.      {
  1120.         ...
  1121.      };
  1122.  
  1123.      When defined in the EXE, the same must be prototyped as:
  1124.  
  1125.      class huge A
  1126.      {
  1127.           ...
  1128.      };
  1129.      // see User's Guide for more information
  1130.  
  1131.      Then link with /c and /C on (both case sensitive link and case
  1132.      sensitive exports ENABLED) when building BOTH the .DLL and the
  1133.      calling.EXE.
  1134.  
  1135.  
  1136. PROBLEM:
  1137.      OWL and undefined symbols.
  1138.  
  1139. SOLUTION:
  1140.      If you're linking to the static libraries:
  1141.           - with BC 2.0, link in owlwx.lib, tclasswx.lib, and
  1142.             sallocwx.lib. (You don't need sallocwx.lib with BC
  1143.             v 3.x ).
  1144.  
  1145.           - do NOT define _CLASSDLL in the code generation
  1146.             dialog, or before including owl.h.
  1147.  
  1148.           - link with /c and /C. (from IDE, under linker
  1149.             options, case sensitive link and case sensitive
  1150.             exports).
  1151.  
  1152.           - Do NOT compile with -K or unsigned char's on. You
  1153.             will get several undefined symbols in this case.
  1154.  
  1155.      If you're linking to the OWL .DLL, DO define _CLASSDLL before
  1156.      including OWL.H, and use /c and /C linker options (both Case
  1157.      Sensitive Link and Case Sensitive Exports ENABLED).
  1158.  
  1159.  
  1160. PROBLEM:
  1161.      With an OWL application, wsprintf is undefined in module when
  1162.      linking to the static libraries.
  1163.  
  1164. SOLUTION:
  1165.      Link with /C (case sensitive exports ENABLED).
  1166.  
  1167.  
  1168. PROBLEM:
  1169.      _main is an undefined symbol.
  1170.  
  1171. SOLUTION:
  1172.      main is the entry point for every DOS C/C++ program. Make sure
  1173.      you write a function called main (all lowercase) in your program.
  1174.      If you have a project file loaded, make sure your source code
  1175.      file (.c or .cpp file) which has main in it is listed in the .prj
  1176.      file. Make sure generate underbars is turned on.
  1177.  
  1178.  
  1179. PROBLEM:
  1180.      iostream members, like << operator are undefined
  1181.  
  1182. SOLUTION:
  1183.      Turn options | compiler | code generation | unsigned chars off
  1184.      (do not use -K on the command line).
  1185.  
  1186.  
  1187. PROBLEM:
  1188.      Getting undefined symbols LLSH, SCOPY FMUL, FDIV, etc
  1189.  
  1190. SOLUTION:
  1191.      Many of the helper functions have changed names from Turbo C
  1192.      2.0 to Borland C++. This functions were called from Turbo C 2.0.
  1193.      The solution is to recompile any .OBJ or .LIB them with Borland
  1194.      C++.
  1195.  
  1196.  
  1197. SNOOPING AT THE REAL NAMES:
  1198. ---------------------------
  1199. An .OBJ file is a collection of records. When you call a function or
  1200. reference a symbol not defined in your module, the compiler generates
  1201. an external definition record in the OBJ. This external definition
  1202. record has the symbol which the linker must resolve. When you define a
  1203. function, or make storage for some data, the compiler generates a
  1204. public definition record for that module (unless you declared the item
  1205. as static, that makes it private to that module). One of the tasks of
  1206. the Linker is to match Public Definitions and External
  1207. Definitions(PUBDEFs and EXTDEFs).
  1208.  
  1209. To see the symbols the LINKER has to deal with, use TDUMP.EXE provided
  1210. with the Borland C++ package. For example:
  1211.  
  1212.     tdump -m -oiEXTDEF some.obj
  1213.  
  1214. The above shows all the EXTDEF (external definition) records in an .OBJ
  1215. file. Be sure to add the -m option when coding in C++.
  1216.  
  1217.     tdump -m -oiPUBDEF some.obj
  1218.  
  1219. The above will display all the PUBDEF (public definition) records.
  1220.  
  1221. Let's assume you've purchased a third party library and a symbol
  1222. provided the library is unresolved; the possible steps in
  1223. identifying the problem could include:
  1224.  
  1225.      - Create a Listing of symbols in the Library using TLIB. For
  1226.        example:
  1227.           TLIB NEWLIB.LIB, NEWLIB.LST
  1228.  
  1229.      - TDUMP the .OBJ file which was created from the .C/.CPP
  1230.        module calling the desired function.
  1231.           TDUMP  -m -oiEXTDEF MYCODE.OBJ MYCODE.LST
  1232.  
  1233.      - Attempt to find any discrepancies between the name in
  1234.        NEWLIB.LST and the one in MYCODE.LST and ascertain that
  1235.        the Library does indeed provide the desired function.
  1236.  
  1237. Windows Programmers will find the IMPDEF.EXE utility (in addition to
  1238. TDUMP and TLIB) a very useful tool to help identify unresolved symbols
  1239. when DLLs and/or Import Libraries are involved.
  1240.  
  1241.  
  1242. ===================================================================
  1243. 4.  Borland Open Architecture:  Name Mangling
  1244. ===================================================================
  1245. There are four basic forms of encoded names in Borland C++:
  1246.  
  1247. 1. @className@functionName$args
  1248.  
  1249. This encoding denotes a member function Name belonging to
  1250. class Name and having arguments args.
  1251.  
  1252. Class names are encoded directly. The following example shows a
  1253. className in an encoded name:
  1254.  
  1255.       @className@...
  1256.  
  1257. The class name may be followed by a single digit; the digit value
  1258. contains the following bits (these can be combined):
  1259.  
  1260.     0x01 : the class uses a far vtable
  1261.  
  1262.     0x02 : the class uses the -po calling convention
  1263.  
  1264.     0x04 : the class has an RTTI-compatible virtual table; this bit is
  1265.            only used when encoding the name of the virtual table for
  1266.            the class
  1267.  
  1268. The digit is encoded as an ASCII representation of the bit mask
  1269. value, with 1 subtracted (so that, for example, the class prefix for a
  1270. class 'myfunc' that uses far vtables would be '@myfunc@0').
  1271.  
  1272. See the next section on the encoding of function names and argument
  1273. types.
  1274.  
  1275. 2. @functionName$args
  1276.  
  1277. This form of encoding denotes a function functionName with arguments
  1278. args.
  1279.  
  1280. 3. @className@dataMember
  1281.  
  1282. This form of encoding denotes a static data member dataMember
  1283. belonging to class className. Names of classes and data members are
  1284. encoded directly. The following example shows a member myMember in
  1285. class myClass:
  1286.  
  1287.       @myClass@myMember
  1288.  
  1289. 4. @className@
  1290.  
  1291. This name denotes a virtual table for a class className. As mentioned
  1292. previously, class names are encoded directly.
  1293.  
  1294.  
  1295. Encoding of nested and template classes
  1296. ---------------------------------------
  1297. The following form encodes a name of a class lexically nested within
  1298. another class:
  1299.  
  1300.   @outer@inner@...
  1301.  
  1302. A template instance class encodes the name of the template class, along
  1303. with the actual template arguments, in the following way:
  1304.  
  1305.   %templateName$arg1$arg2 ..... $argn%
  1306.  
  1307. Each actual argument starts with a letter, specifying the kind of
  1308. argument it is:
  1309.  
  1310.   o  t type argument
  1311.  
  1312.   o  i nontype integral argument
  1313.  
  1314.   o  g nontype nonmember pointer argument
  1315.  
  1316.   o  m nontype member pointer argument
  1317.  
  1318. The first letter is followed by the encoded type of the argument. For
  1319. a type argument, this code also represents the argument's actual
  1320. value. For other kinds of arguments, the type code is followed by $and
  1321. the argument value, encoded as an ASCII number or symbol name. An
  1322. instance of template<class T, int size> whose name is
  1323. vector<long,100>is encoded as shown in the following example:
  1324.  
  1325.   %vector$tl$ii$100%
  1326.  
  1327.  
  1328. Encoding of function names
  1329. --------------------------
  1330. The encoded function Name might denote either a function name, a
  1331. function such as a function such as a constructor or destructor, an
  1332. overloaded operator, or a type conversion.
  1333.  
  1334.  
  1335. Ordinary functions
  1336. ------------------
  1337. Ordinary function names are encoded directly, as shown in the
  1338. following examples:
  1339.  
  1340.   foo(int) --> @foo$qi sna::foo(void) --> @sna@foo$qv
  1341.  
  1342. The string $qi denotes the integer argument of function myfunc();'$qv'
  1343. denotes no arguments in sna::myfunc.
  1344.  
  1345.  
  1346. Constructors, destructors, and overloaded operators
  1347. ---------------------------------------------------
  1348. The following information covers argument encoding in more
  1349. detail. Constructors, destructors, and overloaded operators encoded
  1350. with a $bcharacter sequence, followed by a character sequence from the
  1351. following table:
  1352.  
  1353.             Character        Meaning Sequence
  1354.             _________________________________
  1355.  
  1356.             ctr              constructor
  1357.             dtr              destructor
  1358.             add              +
  1359.             adr              &
  1360.             and              &
  1361.             arow             ->
  1362.             arwm             ->*
  1363.             asg              =
  1364.             call             ()
  1365.             cmp              ~
  1366.             coma             ,
  1367.             dec              --
  1368.             dele             delete
  1369.             div              /
  1370.             eql              ==
  1371.             geq              >=
  1372.             gtr              >
  1373.             inc              ++
  1374.             ind              *
  1375.             land             &&
  1376.             lor              ||
  1377.             leq              <=
  1378.             lsh              <<
  1379.             lss              <
  1380.             mod              %
  1381.             mul              *
  1382.             neq              !=
  1383.             new              new
  1384.             not              !
  1385.             or               |
  1386.             rand             &=
  1387.             rdiv             /=
  1388.             rlsh             <<=
  1389.             rmin             -=
  1390.             rmod             %=
  1391.             rmul             *=
  1392.             ror              |=
  1393.             rplu             +=
  1394.             rrsh             >>=
  1395.             rsh              >>
  1396.             rxor             ^=
  1397.             sub              -
  1398.             subs             []
  1399.             xor              ^
  1400.             nwa              new[]
  1401.             dla              delete []
  1402.             __________________________________
  1403.  
  1404. The following examples show how arguments are encoded with character
  1405. sequences, add, ctr, and dtr from the previous table:
  1406.  
  1407.   operator+(int)  -->     @$badd$qi plot::plot() --> @plot@$bctr$qv
  1408.   plot::~plot()   --> @plot@$bdtr$qv
  1409.  
  1410. The string $qv denotes no arguments in the plot constructor or
  1411. destructor.
  1412.  
  1413.  
  1414. Type conversions
  1415. ----------------
  1416. Encoding of type conversions accomplished with the $o character
  1417. sequence, followed by distinguishing return type of the conversion as
  1418. part of function name. The return type follows the rules for argument
  1419. encoding, explained later. The lack of arguments in one version is
  1420. made explicit in the mangling by adding $qv the end of the encoded
  1421. string.
  1422.  
  1423. Example:
  1424.  
  1425.   myfunc::operator int() --> @myfunc@$oi$qv myfunc::operator char *()
  1426.   -->     @myfunc@$opzc$qv
  1427.  
  1428. The i following $o in the first example denotes int; the pzc in the
  1429. second example denotes a near pointer to an unsigned char.
  1430.  
  1431.  
  1432. Encoding of arguments
  1433. ----------------------
  1434. The number and combinations of function arguments make argument
  1435. encoding the most complex aspect of name mangling.
  1436.  
  1437. Argument lists for functions begin with the characters $q. Type
  1438. qualifiers are then encoded as shown in the following table:
  1439.          _____________________________
  1440.  
  1441.           Character   Meaning Sequence
  1442.          _____________________________
  1443.  
  1444.            up          huge
  1445.            ur          _seg
  1446.            u           unsigned
  1447.            z           signed
  1448.            x           const
  1449.            w           volatile
  1450.            ____________________________
  1451.  
  1452. Encoding of built-in types follows that for applicable type
  1453. qualifiers, in accordance with the following table:
  1454.  
  1455.            ______________________________
  1456.  
  1457.              Character   Meaning Sequence
  1458.            ______________________________
  1459.  
  1460.              v           void
  1461.              c           char
  1462.              s           short
  1463.              i           int
  1464.              l           long
  1465.              f           float
  1466.              d           double
  1467.              g           long double
  1468.              e           ...
  1469.            ______________________________
  1470.  
  1471. Encoding of non-built-in types follows that for applicable type
  1472. qualifiers, in accordance with the following table:
  1473.  
  1474.          ______________________________
  1475.  
  1476.            Character   Meaning Sequence
  1477.          ______________________________
  1478.  
  1479.            <a digit>   (an enumeration or class name)
  1480.            p           near *
  1481.            r           near &
  1482.            m           far &
  1483.            n           far *
  1484.            a           array
  1485.            M           member pointer (followed by class and
  1486.                        base type)
  1487.            ______________________________
  1488.  
  1489. The appearance of one or more digits indicates that an enumeration or
  1490. class name follows; the value of the digit(s) denotes the length of
  1491. the name, as shown in the following examples:
  1492.  
  1493.   foo::myfunc(myClass near&)      is mangled as @foo@myfunc$qr7myClass
  1494.   foo::myfunc(anotherClass near&) is mangled as
  1495.   @foo@myfunc$qr12anotherClass
  1496.  
  1497. A character x or w may appear after p, r, m, or n to denote a constant
  1498. or volatile type qualifier, respectively. The character q appearing
  1499. after one of these characters denotes a function with arguments the
  1500. follow in the encoded name, up to the appearance of a $ character, and
  1501. finally a return type is encoded. The following example show how these
  1502. encoding rules are applied:
  1503.  
  1504.   @foo@myfunc$qpxzc      is mangled as foo::myfunc(const char near*)
  1505.   @func1$qxi is mangled as   func1(const int) @foo@myfunc$qpqii$i is
  1506.   mangled as foo:myfunc(int (near*)(int,int))
  1507.  
  1508. Array types are encoded as a, followed by a dimension encoded as an
  1509. ASCII decimal number and a $, and finally the element type, as shown
  1510. in the following example.
  1511.  
  1512.   myfunc( int (*x)[20] )    is mangled as @myfunc$qpa20$i
  1513.  
  1514. Encoded arguments are concatenated in the order of appearance in the
  1515. function call. The character t followed by an ASCII character encodes
  1516. the arguments when a number of identical non-builtin types are
  1517. function arguments. The ASCII character, ranging from ASCII 31H -
  1518. 39Hand 61H - 7FH (1 to 9 and a onward), denotes which argument type to
  1519. duplicate, as shown in the following example:
  1520.  
  1521.   @plot@func1$qdddiiilllpzctata is unmangled to plot::func1(double,
  1522.           double, double, int, int, int, long, long, long, char near*,
  1523.           char near*, char near*)
  1524.  
  1525. The two duplicate ta character sequences at the end of the encoded
  1526. name denote the tenth argument, encoded as pzc.
  1527.  
  1528. /*************************************************************************/
  1529.  
  1530.